#include "../include/comm.h"
#include "../include/user_list.h"
#include "../include/client_list.h"

extern UserNode *user_head;

extern ClientNode *client_head;

void concat_list(char *list)
{
    ClientNode *p = client_head->next;
    while(p != NULL)
    {
        sprintf(list + strlen(list), "%s", p->nickname);
        if(p->next != NULL)
        {
            strcat(list, "#");
        }
        else
        {
            strcat(list, "\n");
        }
        p = p->next;
    }
}

void send_list()
{
    char list[2048] = "getlist#";
    concat_list(list);
    ClientNode *p = client_head->next;
    while(p != NULL)
    {
        send(p->sock, list, strlen(list), 0);
        p = p->next;
    }
}

void *server_recv(void *arg)
{
    ClientNode *src_cli = (ClientNode *)arg;
    char rbuf[2048];
    while(1)
    {
        memset(rbuf, 0, sizeof(rbuf));

        int cnt = 0;
        int ret;
        char c;
        while(1)
        {   
            ret = recv(src_cli->sock, &c, 1, 0);
            if(ret == 0)
            {
                printf("套接字为%d，IP为%s，端口号为%hu的客户端退出了\n", src_cli->sock, src_cli->ip, src_cli->port);
                remove_client_node(client_head, src_cli);
                show_client(client_head);
                send_list();
                return NULL;
            }
            else if(ret < 0)
            {
                fprintf(stderr, "接收套接字为%d，IP为%s，端口号为%hu的客户端的信息失败:%s\n", src_cli->sock, src_cli->ip, src_cli->port, strerror(errno));
                return NULL;
            }

            rbuf[cnt++] = c;
            if(c == '\n')
            {
                break;
            }
        }
        rbuf[cnt - 1] = '\0';
    
        char sbuf[2048] = {0};
        // char ip[100] = {0};
        // uint16_t port;
        char *p = strtok(rbuf, "@");

        if(strcmp(p, "login") == 0)
        {
            char username[100] = {0};
            char password[100] = {0};
            p = strtok(NULL, "@");
            strncpy(username, p, sizeof(username));
            p = strtok(NULL, "@");
            strncpy(password, p, sizeof(password));

            char *nickname;
            if((nickname = find_user(user_head, username, password)) != NULL)
            {
                strncpy(src_cli->username, username, sizeof(src_cli->username));
                strncpy(src_cli->nickname, nickname, sizeof(src_cli->nickname));
                printf("套接字为%d，IP为%s，端口号为%hu的客户端登录成功，用户名为：%s，昵称为：%s\n", src_cli->sock, src_cli->ip, src_cli->port, src_cli->username, src_cli->nickname);
                snprintf(sbuf, sizeof(sbuf), "%s\n", nickname);
                send(src_cli->sock, sbuf, strlen(sbuf), 0);
                send_list();
            }
            else
            {
                send(src_cli->sock, "Failed\n", strlen("Failed\n"), 0);
            }
        }
        else if(strcmp(p, "chat") == 0)
        {
            char nickname[100] = {0};
            p = strtok(NULL, "@");
            strncpy(nickname, p, sizeof(nickname));
            ClientNode *dest_cli = find_client_by_nickname(client_head, nickname);

            p = strtok(NULL, "@");
            snprintf(sbuf, sizeof(sbuf), "chat#%s#%s\n", src_cli->nickname, p);

            send(dest_cli->sock, sbuf, strlen(sbuf), 0);
        }
        else if(strcmp(p, "sendfile") == 0)
        {
            char nickname[100] = {0};
            p = strtok(NULL, "@");
            strncpy(nickname, p, sizeof(nickname));
            ClientNode *dest_cli = find_client_by_nickname(client_head, nickname);

            p = strtok(NULL, "@");
            char filename[100] = {0};
            strncpy(filename, p, sizeof(filename));

            p = strtok(NULL, "@");
            long filesize = atol(p);

            snprintf(sbuf, sizeof(sbuf), "sendfile#%s#%s#%s\n", src_cli->nickname, filename, p);
            send(dest_cli->sock, sbuf, strlen(sbuf), 0);

            // 开始读取文件内容
            long received = 0;
            while(received < filesize)
            {
                memset(sbuf, 0, sizeof(sbuf));
                ret = recv(src_cli->sock, sbuf, sizeof(sbuf), 0);
                if(ret == 0)
                {
                    printf("套接字为%d，IP为%s，端口号为%hu的客户端退出了\n", src_cli->sock, src_cli->ip, src_cli->port);
                    remove_client_node(client_head, src_cli);
                    show_client(client_head);
                    send_list();
                    return NULL;
                }
                else if(ret < 0)
                {
                    fprintf(stderr, "接收套接字为%d，IP为%s，端口号为%hu的客户端的信息失败:%s\n", src_cli->sock, src_cli->ip, src_cli->port, strerror(errno));
                    return NULL;
                }
                send(dest_cli->sock, sbuf, ret, 0);
                received += ret;
            }
        }
        else if(strcmp(p, "emoji") == 0)
        {
            char nickname[100] = {0};
            p = strtok(NULL, "@");
            strncpy(nickname, p, sizeof(nickname));
            ClientNode *dest_cli = find_client_by_nickname(client_head, nickname);

            p = strtok(NULL, "@");
            char emoji_name[100] = {0};
            strncpy(emoji_name, p, sizeof(emoji_name));

            p = strtok(NULL, "@");
            long filesize = atol(p);

            snprintf(sbuf, sizeof(sbuf), "emoji#%s#%s#%s\n", src_cli->nickname, emoji_name, p);
            send(dest_cli->sock, sbuf, strlen(sbuf), 0);

            // 开始读取文件内容
            long received = 0;
            while(received < filesize)
            {
                memset(sbuf, 0, sizeof(sbuf));
                ret = recv(src_cli->sock, sbuf, sizeof(sbuf), 0);
                if(ret == 0)
                {
                    printf("套接字为%d，IP为%s，端口号为%hu的客户端退出了\n", src_cli->sock, src_cli->ip, src_cli->port);
                    remove_client_node(client_head, src_cli);
                    show_client(client_head);
                    send_list();
                    return NULL;
                }
                else if(ret < 0)
                {
                    fprintf(stderr, "接收套接字为%d，IP为%s，端口号为%hu的客户端的信息失败:%s\n", src_cli->sock, src_cli->ip, src_cli->port, strerror(errno));
                    return NULL;
                }
                send(dest_cli->sock, sbuf, ret, 0);
                received += ret;
            }
        }
    }
    return NULL;
}